package com.bzyd.jpa.service;

import com.bzyd.jpa.dao.OrderDao;
import com.bzyd.jpa.entity.Order;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class OrderService {

    @Autowired
    private OrderDao orderDao;

    /**
     * 订单分页查询
     *
     * <p>
     * 复杂条件分页查询主要有两种实现方式，一是@Query编写SQL实现，但此种方式过多使用会使项目中遍地SQL，失去使用JPA框架的初衷
     * 二是通过JpaSpecificationExecutor接口实现。JpaSpecificationExecutor不属于JpaRepository体系，它主要通过自定义断言实现条件过滤
     * 使用Page<T> findAll(Specification<T> var1, Pageable var2)方法
     * </p>
     *
     * @param orderNo         订单编号
     * @param orderName       订单名称
     * @param createTimeStart 创建时间开始，yyyy-mm-dd
     * @param pageIndex       当前查询第几页
     * @param pageSize        当前页查询几条数据
     * @return
     */
    public Page<Order> findOrderByPage(String orderNo, String orderName, String createTimeStart, int pageIndex, int pageSize) {

        //构造查询条件
        Specification<Order> specification = new Specification<Order>() {

            /**
             * 构造断言
             * @param root 实体对象引用
             * @param criteriaQuery 规则查询对象
             * @param criteriaBuilder 规则构建对象
             * @return 断言
             */
            @Override
            public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicateList = new ArrayList<>();

                //订单编号精确匹配
                if (StringUtils.isNotBlank(orderNo)) {
                    Predicate predicate = criteriaBuilder.equal(root.get("orderNo").as(String.class), orderNo);//等于匹配
                    predicateList.add(predicate);
                }

                //订单名称模糊查询
                if (StringUtils.isNotBlank(orderName)) {
                    Predicate predicate = criteriaBuilder.like(root.get("orderName").as(String.class), "%" + orderName + "%");//模糊匹配
                    predicateList.add(predicate);
                }

                //创建日期大于等于
                if (StringUtils.isNotBlank(createTimeStart)) {
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                    Date startDate = null;
                    try {
                        startDate = format.parse(createTimeStart);
                    } catch (ParseException e) {
                        log.error("日期解析异常！");
                        startDate = new Date();
                    }
                    Predicate predicate = criteriaBuilder.greaterThanOrEqualTo(root.get("createTime").as(Date.class), startDate);//大于等于
                    predicateList.add(predicate);
                }

                return criteriaBuilder.and(predicateList.toArray(new Predicate[0]));
            }
        };


        //分页信息
        Pageable pageable = PageRequest.of(pageIndex - 1, pageSize);//new PageRequest()已过时
        return orderDao.findAll(specification, pageable);
    }
}
